package com.xxx.mch.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.xxx.mch.dao.ResultScoreMapper;
import com.xxx.mch.dao.ResultScoreTemplateMapper;
import com.xxx.mch.domain.dto.UserResultScoreDto;
import com.xxx.mch.domain.po.ResultScore;
import com.xxx.mch.domain.po.ResultScoreTemplate;
import com.xxx.mch.domain.po.TotalScore;
import com.xxx.mch.domain.request.QueryScoreRequest;
import com.xxx.mch.exception.BusinessException;
import com.xxx.mch.service.ScoreService;
import com.xxx.mch.service.TotalScoreService;
import java.math.BigDecimal;
import javax.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.weekend.Weekend;
import tk.mybatis.mapper.weekend.WeekendCriteria;

import java.util.List;
import java.util.Objects;

/**
 * @author FengHaixin
 * @description 一句话描述该文件的用途
 * @date 2020-02-25
 */
@Service
public class ResultScoreServiceImpl implements ScoreService<ResultScore, ResultScoreTemplate>
{
    @Autowired
    private ApplicationContext applicationContext;

    @Resource
    private ResultScoreMapper resultScoreMapper;

    @Resource
    private TotalScoreService totalScoreService;

    @Resource
    private ResultScoreTemplateMapper resultScoreTemplateMapper;


    @Override
    @Transactional (rollbackFor = Exception.class)
    public int saveScore(ResultScore resultScore)
    {
        ResultScoreTemplate template = resultScoreTemplateMapper.selectByPrimaryKey(resultScore.getTypeId());
        if (Objects.isNull(template))
        {
            throw new BusinessException("模板不存在");
        }
        if (Objects.nonNull(template.getAwardCoefficient()) && Objects.nonNull(resultScore.getAwardCount()))
        {
            resultScore.setAwardScore(template.getAwardCoefficient().multiply(new BigDecimal(resultScore.getAwardCount())));
        }
        if (Objects.nonNull(template.getPraiseCoefficient()) && Objects.nonNull(resultScore.getPraiseCount()))
        {
            resultScore.setPraiseScore(template.getPraiseCoefficient().multiply(new BigDecimal(resultScore.getPraiseCount())));
        }
        if (Objects.nonNull(template.getReadCoefficient()) && Objects.nonNull(resultScore.getReadCount()))
        {
            resultScore.setReadScore(template.getReadCoefficient().multiply(new BigDecimal(resultScore.getReadCount())));
        }
        if (Objects.nonNull(template.getPetroChinaCoefficient()) && Objects.nonNull(resultScore.getPetroChinaCount()))
        {
            resultScore.setPetroChinaScore(template.getPetroChinaCoefficient().multiply(new BigDecimal(resultScore.getPetroChinaCount())));

        }
        if (Objects.nonNull(template.getSocialMediaCoefficient()) && Objects.nonNull(resultScore.getSocialMediaCount()))
        {
            resultScore.setSocialMediaScore(
                    template.getSocialMediaCoefficient().multiply(new BigDecimal(resultScore.getSocialMediaCount())));
        }

        resultScore.setScore(resultScore.getAwardScore()
                                        .add(resultScore.getPraiseScore())
                                        .add(resultScore.getReadScore())
                                        .add(resultScore.getPetroChinaScore())
                                        .add(resultScore.getSocialMediaScore()));
        int count = resultScoreMapper.insertSelective(resultScore);

        TotalScore totalScore = new TotalScore();
        totalScore.setUid(resultScore.getUid());
        totalScore.setResultScore(resultScore.getScore());
        totalScore.setAllowanceScore(resultScore.getScore());
        applicationContext.publishEvent(totalScore);
        return count;
    }


    @Override
    public List<ResultScore> queryTypeFilter(QueryScoreRequest queryScoreRequest)
    {
        return resultScoreMapper.queryTypeFilter(queryScoreRequest);
    }


    @Override
    public BigDecimal querySumScore(QueryScoreRequest queryScoreRequest)
    {
        return resultScoreMapper.querySumScore(queryScoreRequest);
    }


    @Override
    public PageInfo<ResultScore> queryScoreRecord(QueryScoreRequest queryScoreRequest)
    {
        Page<ResultScore> page = PageHelper.startPage(queryScoreRequest.getPage(), queryScoreRequest.getPageSize());
        PageInfo<ResultScore> pageInfo = page.doSelectPageInfo(() -> {
            Weekend<ResultScore> weekend = new Weekend<>(ResultScore.class);
            WeekendCriteria<ResultScore, Object> criteria = weekend.weekendCriteria();
            criteria.andEqualTo(ResultScore::getUid, queryScoreRequest.getUid());
            criteria.andCondition(
                    "DATE_FORMAT(STR_TO_DATE(create_time,\"%Y-%m-%d %H:%i:%s\"), '%Y-%m')= '" + queryScoreRequest.getDate() + "'");
            if (!CollectionUtils.isEmpty(queryScoreRequest.getFilters()))
            {
                criteria.andIn(ResultScore::getTypeId, queryScoreRequest.getFilters());
            }
            resultScoreMapper.selectByExample(weekend);
        });
        return pageInfo;
    }


    @Override
    public void createOrUpdateTemplate(List<ResultScoreTemplate> templateRequestList)
    {
        if (CollectionUtils.isEmpty(templateRequestList))
        {
            return;
        }
        templateRequestList.forEach(resultScoreTemplate -> {
            resultScoreTemplateMapper.updateByPrimaryKeySelective(resultScoreTemplate);
        });
    }


    @Override
    public UserResultScoreDto queryUserScore(String uid, String month)
    {
        Weekend<ResultScore> weekend = new Weekend<>(ResultScore.class);
        WeekendCriteria<ResultScore, Object> criteria = weekend.weekendCriteria();
        criteria.andEqualTo(ResultScore::getUid, uid);
        criteria.andCondition("DATE_FORMAT(STR_TO_DATE(create_time,\"%Y-%m-%d %H:%i:%s\"), '%Y-%m')= '" + month + "'");
        List<ResultScore> resultScores = resultScoreMapper.selectByExample(weekend);
        if (CollectionUtils.isEmpty(resultScores))
        {
            return new UserResultScoreDto();
        }

        return resultScores.stream().reduce((prev, next) -> {
            ResultScore resultScore = new ResultScore();
            resultScore.setReadCount(prev.getReadCount() + next.getReadCount());
            resultScore.setAwardCount(prev.getAwardCount() + next.getAwardCount());
            resultScore.setPraiseCount(prev.getPraiseCount() + next.getPraiseCount());
            resultScore.setScore(prev.getScore().add(next.getScore()));
            resultScore.setPetroChinaCount(prev.getPetroChinaCount() + next.getPetroChinaCount());
            resultScore.setSocialMediaCount(prev.getSocialMediaCount() + next.getSocialMediaCount());
            return resultScore;

        }).map(resultScore -> {
            UserResultScoreDto scoreDto = new UserResultScoreDto();
            BeanUtils.copyProperties(resultScore, scoreDto);
            TotalScore totalScore = totalScoreService.queryTotalScore(uid, month);
            if (Objects.nonNull(totalScore))
            {
                scoreDto.setScore(totalScore.getTotalScore());
            }
            return scoreDto;
        }).orElse(new UserResultScoreDto());
    }


    public List<ResultScoreTemplate> getTemplate()
    {
        return resultScoreTemplateMapper.selectAll();
    }
}
